import { reactive, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useAccountStore } from '@/store/account'
import { usePopupMessageStore } from '@/store/popup-message'
import { useSignUpStore } from '@/store/sign-up'
import { $t } from '@/i18n'
import { useYup, validate } from '@/plugins/yup'
import { checkAccountExist } from '@use/validator'
import { CHECK_ACCOUNT_EXISTS } from '@const'
import { postback } from '@/utils/postback'
import { useExecutionLock } from '@/compositions/utils'
import { trackEvent } from '@/gtm'
import API from '@/http'

export function useSignUp(onSignUp, chKey = null) {
  const signUpStore = useSignUpStore()
  const { account } = storeToRefs(signUpStore)

  const form = reactive({
    account: {
      value: '',
      error: '',
      check: false,
      canUse: true,
    },
    email: {
      value: '',
      error: '',
      check: false,
      canUse: true,
    },
    password: {
      value: '',
      error: '',
      check: false,
    },
  })

  watch(form.account, (newValue) => (account.value = newValue.value))

  const { string } = useYup()
  const schemaAccount = string()
    .required()
    .min(4)
    .max(20)
    .matches(/^[a-zA-Z0-9_]*$/)

  const schemaEmail = string().required().email()
  const schemaPassword = string().required().min(8)

  const accountAppendIcon = ref('')
  const emailAppendIcon = ref('')

  function getAppendIcon(element) {
    if (!element.value) return ''
    return element.canUse && element.check ? 'yesActive' : 'noActive'
  }
  async function checkAccount() {
    try {
      if (await validate(schemaAccount, form.account)) {
        await checkAccountExist(form.account, CHECK_ACCOUNT_EXISTS.ACCOUNT)
        accountAppendIcon.value = getAppendIcon(form.account)
      }
    } catch (e) {
      console.error(`[validate account schema] ${e}`)
    }
  }
  async function checkEmail() {
    try {
      if (await validate(schemaEmail, form.email)) {
        await checkAccountExist(form.email, CHECK_ACCOUNT_EXISTS.EMAIL)
        emailAppendIcon.value = getAppendIcon(form.email)
      }
    } catch (e) {
      console.error(`[validate email schema] ${e}`)
    }
  }

  const { disabled, onExecute } = useExecutionLock()

  async function onConfirm() {
    const validations = [
      validate(schemaAccount, form.account),
      validate(schemaEmail, form.email),
      validate(schemaPassword, form.password),
    ]

    await Promise.all(validations)

    for (const key in form) {
      if (form[key].check === false) return
      if ('canUse' in form[key] && form[key].canUse === false) return
    }

    await onExecute(onRegister)
  }

  const { open: openMessage } = usePopupMessageStore()
  const { login } = useAccountStore()
  const signUpErrMsg = ref('')

  async function onRegister() {
    try {
      const payload = {
        account: form.account.value,
        password: form.password.value,
        email: form.email.value,
      }

      if (chKey) payload.ch = chKey

      const response = await API.Auth.register({ data: payload })
      login(response)
      signUpStore.$reset()

      trackEvent({ key: 43 })
      await postback()
      openMessage($t('message.registerSuccess'))
      onSignUp?.()
    } catch (e) {
      console.error(`[auth register] ${e.message}`)
      signUpErrMsg.value = e.message
      throw new Error(e)
    }
  }

  return {
    form,
    accountAppendIcon,
    emailAppendIcon,
    disabled,
    signUpErrMsg,
    checkAccount,
    checkEmail,
    onConfirm,
  }
}
